package tech.konata.packetfix.mixins;

import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.vialoadingbase.ViaLoadingBase;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.MathHelper;
import net.minecraft.world.World;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.Shadow;
import tech.konata.packetfix.PluginMain;

@Mixin(EntityLivingBase.class)
public class MixinEntityLivingBase extends Entity {

    public MixinEntityLivingBase(World world) {
        super(world);
    }

    @Shadow
    private int jumpTicks;

    @Shadow
    protected int newPosRotationIncrements;

    @Shadow
    protected double newPosX;
    @Shadow
    protected double newPosY;
    @Shadow
    protected double newPosZ;

    @Shadow
    protected double newRotationYaw;
    @Shadow
    protected double newRotationPitch;

    @Shadow
    public boolean isServerWorld() {
        return false;
    }
    @Shadow
    protected boolean isMovementBlocked() {
        return false;
    }

    @Shadow
    protected boolean isJumping;
    @Shadow
    public float moveStrafing;
    @Shadow
    public float moveForward;
    @Shadow
    protected float randomYawVelocity;

    @Overwrite
    public void onLivingUpdate() {
        if (this.jumpTicks > 0) {
            --this.jumpTicks;
        }

        if (this.newPosRotationIncrements > 0) {
            double var1 = this.posX + (this.newPosX - this.posX) / (double)this.newPosRotationIncrements;
            double var3 = this.posY + (this.newPosY - this.posY) / (double)this.newPosRotationIncrements;
            double var5 = this.posZ + (this.newPosZ - this.posZ) / (double)this.newPosRotationIncrements;
            double var7 = MathHelper.wrapAngleTo180_double(this.newRotationYaw - (double)this.rotationYaw);
            this.rotationYaw = (float)((double)this.rotationYaw + var7 / (double)this.newPosRotationIncrements);
            this.rotationPitch = (float)((double)this.rotationPitch + (this.newRotationPitch - (double)this.rotationPitch) / (double)this.newPosRotationIncrements);
            --this.newPosRotationIncrements;
            this.setPosition(var1, var3, var5);
            this.setRotation(this.rotationYaw, this.rotationPitch);
        } else if (!this.isServerWorld()) {
            this.motionX *= 0.98;
            this.motionY *= 0.98;
            this.motionZ *= 0.98;
        }

        double movementThreshold = 0.005D;
        if (ViaLoadingBase.getInstance().getTargetVersion().newerThanOrEqualTo(ProtocolVersion.v1_12_2) && PluginMain.packetFix.isEnabled()) {
            movementThreshold = 0.003;
        }

        if (Math.abs(this.motionX) < movementThreshold)
        {
            this.motionX = 0.0D;
        }

        if (Math.abs(this.motionY) < movementThreshold)
        {
            this.motionY = 0.0D;
        }

        if (Math.abs(this.motionZ) < movementThreshold)
        {
            this.motionZ = 0.0D;
        }

        this.worldObj.theProfiler.startSection("ai");
        if (this.isMovementBlocked()) {
            this.isJumping = false;
            this.moveStrafing = 0.0F;
            this.moveForward = 0.0F;
            this.randomYawVelocity = 0.0F;
        } else if (this.isServerWorld()) {
            this.worldObj.theProfiler.startSection("newAi");
            this.updateEntityActionState();
            this.worldObj.theProfiler.endSection();
        }

        this.worldObj.theProfiler.endSection();
        this.worldObj.theProfiler.startSection("jump");
        if (this.isJumping) {
            if (this.isInWater()) {
                this.updateAITick();
            } else if (this.isInLava()) {
                this.handleJumpLava();
            } else if (this.onGround && this.jumpTicks == 0) {
                this.jump();
                this.jumpTicks = 10;
            }
        } else {
            this.jumpTicks = 0;
        }

        this.worldObj.theProfiler.endSection();
        this.worldObj.theProfiler.startSection("travel");
        this.moveStrafing *= 0.98F;
        this.moveForward *= 0.98F;
        this.randomYawVelocity *= 0.9F;
        this.moveEntityWithHeading(this.moveStrafing, this.moveForward);
        this.worldObj.theProfiler.endSection();
        this.worldObj.theProfiler.startSection("push");
        if (!this.worldObj.isRemote) {
            this.collideWithNearbyEntities();
        }

        this.worldObj.theProfiler.endSection();
    }

    @Shadow
    protected void collideWithNearbyEntities() {

    }

    @Shadow
    public void jump() {

    }

    @Shadow
    public void moveEntityWithHeading(float var1, float var2) {

    }

    @Shadow
    protected void handleJumpLava() {

    }

    @Shadow
    protected void updateAITick() {

    }

    @Shadow
    public void updateEntityActionState() {

    }

    @Override
    @Shadow
    public void entityInit() {

    }

    @Override
    @Shadow
    public void readEntityFromNBT(NBTTagCompound nbtTagCompound) {

    }

    @Override
    @Shadow
    public void writeEntityToNBT(NBTTagCompound nbtTagCompound) {

    }
}
